package org.rsbot.bot;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.rsbot.Application;
import org.rsbot.client.Loader;
import org.rsbot.loader.ClientLoader;
import org.rsbot.loader.script.ParseException;
import org.rsbot.util.GlobalConfiguration.Paths;

public class RSLoader extends Applet
  implements Runnable, Loader
{
  private final Logger log = Logger.getLogger(RSLoader.class.getName());
  private static final long serialVersionUID = 6288499508495040201L;
  private Applet client;
  private Runnable loadedCallback;
  private String targetName;
  private Dimension size = Application.getPanelSize();
  public RSClassLoader classLoader;

  public final synchronized void destroy()
  {
    if (this.client != null)
      this.client.destroy();
  }

  public boolean isShowing()
  {
    return true;
  }

  public final synchronized void init()
  {
    if (this.client != null)
      this.client.init();
  }

  public final void paint(Graphics paramGraphics)
  {
    if (this.client != null) {
      this.client.paint(paramGraphics);
    } else {
      Font localFont = new Font("Helvetica", 1, 13);
      FontMetrics localFontMetrics = getFontMetrics(localFont);
      paramGraphics.setColor(Color.black);
      paramGraphics.fillRect(0, 0, 768, 503);
      paramGraphics.setColor(new Color(150, 0, 0));
      paramGraphics.drawRect(230, 233, 303, 33);
      String str = "Loading...";
      paramGraphics.setFont(localFont);
      paramGraphics.setColor(Color.WHITE);
      paramGraphics.drawString(str, (768 - localFontMetrics.stringWidth(str)) / 2, 255);
    }
  }

  public void run()
  {
    try
    {
      Class localClass = this.classLoader.loadClass("client");
      this.client = ((Applet)localClass.newInstance());
      this.loadedCallback.run();
      localClass.getMethod("provideLoaderApplet", new Class[] { Applet.class }).invoke(null, new Object[] { this });
      this.client.init();
      this.client.start();
    } catch (Throwable localThrowable) {
      this.log.severe("Unable to load client, please check your firewall and internet connection.");
      File localFile = new File(GlobalConfiguration.Paths.getVersionCache());
      if ((localFile.exists()) && (!localFile.delete())) {
        this.log.warning("Unable to clear cache.");
      }

      this.log.log(Level.SEVERE, "Error reason:", localThrowable);
    }
  }

  public Applet getClient() {
    return this.client;
  }

  public void load() {
    ClientLoader localClientLoader = new ClientLoader();
    try {
      localClientLoader.init(new URL("http://links.powerbot.org/modscript"), new File(GlobalConfiguration.Paths.getModScriptCache()));
      localClientLoader.load(new File(GlobalConfiguration.Paths.getClientCache()), new File(GlobalConfiguration.Paths.getVersionCache()));
      this.targetName = localClientLoader.getTargetName();
      this.classLoader = new RSClassLoader(localClientLoader.getClasses(), new URL("http://" + this.targetName + ".com/"));
    } catch (IOException localIOException) {
      this.log.severe("Unable to load client - " + localIOException.getMessage());
    } catch (ParseException localParseException) {
      this.log.severe("Unable to load client - " + localParseException.toString());
    }
  }

  public void setCallback(Runnable paramRunnable) {
    this.loadedCallback = paramRunnable;
  }

  public String getTargetName() {
    return this.targetName;
  }

  public final synchronized void start()
  {
    if (this.client != null)
      this.client.start();
  }

  public final synchronized void stop()
  {
    if (this.client != null)
      this.client.stop();
  }

  public final void update(Graphics paramGraphics)
  {
    if (this.client != null)
      this.client.update(paramGraphics);
    else
      paint(paramGraphics);
  }

  public final void setSize(int paramInt1, int paramInt2) {
    super.setSize(paramInt1, paramInt2);
    this.size = new Dimension(paramInt1, paramInt2);
  }

  public final Dimension getSize() {
    return this.size;
  }
}